#include "ip.h"

u_char   prefix[16]      = { 0x20, 0x01, 0x0d, 0xa8, 0xff };
u_short  prefix_length   = 5; // including 0xff
u_short  mod             = 256;
u_short  res             = 1;

inline int is_ivi_addr( const u_char *ip6_addr )
{
	return ( *(ip6_addr + 5) == 0xff );
}

//
// Translate IPv4 address to IPv6 address
//
inline void ip_addr4to6( const u_char *ip_addr, u_char *ip6_addr )
{
	memcpy( ip6_addr, prefix, prefix_length );
	memcpy( ip6_addr+prefix_length, ip_addr, 4 );
}

//
// Translate IPv4 header to IPv6 header
//
void ip4to6( const ip_header *ih, ip6_header *ip6h )
{
	// ip6h must be memset to zero before calling this function!
	ip6h->ver_pri = 0x60;
	ip6h->payload = htons( ntohs(ih->length) - (ih->ver_ihl & 0x0f) * 4 );
	ip6h->nexthdr = ih->protocol;
	ip6h->hoplimit = ih->ttl;

	// address mapping
	ip_addr4to6( ih->saddr, ip6h->saddr );
	ip_addr4to6( ih->daddr, ip6h->daddr );

	// to be implemented: port multiplex!!!

	return;
}

//
// Translate IPv6 address to IPv4 address
//
inline void ip_addr6to4( const u_char *ip6_addr, u_char *ip_addr )
{
	memcpy( ip_addr, ip6_addr+prefix_length, 4 );
}

//
// Translate IPv6 header to IPv4 header
//
void ip6to4( const ip6_header *ip6h, ip_header *ih )
{
	// ih must be memset to zero before calling this function!
	ih->ver_ihl = 0x45;
	ih->length = htons( ntohs(ip6h->payload) + 20 );
	ih->ttl = ip6h->hoplimit;
	ih->protocol = ip6h->nexthdr;

	// IVI address mapping
	ip_addr6to4( ip6h->saddr, ih->saddr );
	ip_addr6to4( ip6h->daddr, ih->daddr );

	// to be implemented: port multiplex!!!

	return;
}
